<?php

namespace core\libs;

//单例模式的数据库连接
class db extends \PDO{
    //存储实例的静态成员变量
    private static $_instance;
    //数据库连接静态变量
    private static $_connectSource;
    //连接数据库配置，
    private static $_dbConfig = array();
	// 表前缀
	public static $table_prefix;
    //禁止外部实例化
    public function __construct() {}
	//防止克隆
    public function __clone() {}
    //实例化
    public static function getInstance() {
        if(self::$_instance instanceof self) {
            return self::$_instance;
        }
        self::$_instance = new self();
        return self::$_instance;
	}
	// 连接数据库
	public function connect() {
		// 数据库配置
		self::$_dbConfig = \core\libs\config::get("app", "DB->dsn");
		// 设置表前缀
		self::$table_prefix = \core\libs\config::get("app", "DB->table_prefix");
		//如果不存在数据库连接就创建一个
		if(!self::$_connectSource) {
			try {
				$dsn = 'mysql:host='.self::$_dbConfig['host'].';dbname='.self::$_dbConfig['database'];
				$username = self::$_dbConfig['user'];
				$password = self::$_dbConfig['password'];
				self::$_connectSource = new \PDO($dsn, $username, $password);
				self::$_connectSource->exec("SET NAMES utf8");
			}catch(\PDOException $e) {
				echo $e->getMessage();
			}
		}
		return self::$_connectSource;
	}

    /*	
	 * 获取一条数据	 
	 * @param $table_name 表名
	 * @param $where 条件
	 * @param $field 字段	 
	 */		
	public static function fetch($table_name, $where='', $field='*')	{
		if($where) {
			$where = 'WHERE '.$where;
		}
		
		$results = self::execute_sql("SELECT $field FROM ". self::table($table_name) ." $where");
		return $results->fetch(\PDO::FETCH_ASSOC);
	}
	
	
	/*	
	 * 获取一组数据	 
	 * @param $table_name 表名 
	 * @param $where 条件
	 * @param $field 字段	 
	 */		
	public static function fetchAll($table_name, $where='', $field='*') {
		if($where) {
			$where = 'WHERE '.$where;
		}
		
		$results = self::execute_sql("SELECT $field FROM ". self::table($table_name) ." $where");
		return $results->fetchAll(\PDO::FETCH_ASSOC);
	}
	
	
	/*	
	 * 添加一条数据(支持同时多条数据录入) 
	 * @param $table_name 表名
	 * @param $type 类型：0 正常插入数据，1 key有重复则更新数据，否则插入。
	 * @param $sql 字段	 
	 */		
	public static function insert($table_name, $sql, $type = 0) {
		//insert update 重复则更新，否则插入
		$insert_update = "";
		if($type == 1) {
			$temp = [];
			foreach($sql as $key => $val) {
				$temp[] = "$key=VALUES($key)";
			}
			if($temp) $insert_update = "ON DUPLICATE KEY UPDATE " . implode(",", $temp);
		}
		
		self::execute_sql("INSERT INTO " . self::table($table_name) ." " . self::getValues($sql) . $insert_update);
		
		//最新添加数据的ID
		return self::$_connectSource ->lastInsertId();
	}


	/*	
	 * Replace 覆盖方式插入数据(支持同时多条数据录入) 
	 * @param $table_name 表名
	 * @param $sql 字段	 
	 */		
	public static function insert_replace($table_name, $sql) {
		self::execute_sql("REPLACE INTO " . self::table($table_name) ." " . self::getValues($sql));
		//最新添加数据的ID
		return self::$_connectSource ->lastInsertId();
	}


	/*	
	 * 插入数据，Ignore 有重复则忽略新数据(支持同时多条数据录入) 
	 * @param $table_name 表名
	 * @param $sql 字段	 
	 */		
	public static function insert_ignore($table_name, $sql) {
		self::execute_sql("INSERT IGNORE INTO " . self::table($table_name) ." " . self::getValues($sql));
		//最新添加数据的ID
		return self::$_connectSource ->lastInsertId();
	}


	
	
	/*	
	 * 更新一条数据	 
	 * @param $table_name 表名
	 * @param $sql 字段
	 * @param $where 条件	 
	 */		
	public static function update($table_name, $sql, $where = "") {		
		$upkey = '';
		foreach($sql as $key => $value) {
			if($key.'+1' == $value || $key.'-1' == $value)	{
				$upkey .= $key."=$value,";
			}
			else {
				$upkey .= $key."='$value',";
			}
		}
		
		if($where) {
			$where = 'WHERE '.$where;
		}
		
		self::execute_sql("UPDATE ". self::table($table_name) ." SET " . rtrim($upkey, ",") . " $where");
	}
	
	/*	
	 * 删除数据	 
	 * @param $table_name 表名
	 * @param $where 条件	 
	 */		
	public static function delete($table_name, $where) {
		if($where) $where = 'WHERE '.$where;		
		self::execute_sql("DELETE FROM ". self::table($table_name) ." $where");
	}

	/*	
	 * 获取记录总数	 
	 * @param $table_name 表名
	 * @param $where 条件	 
	 */	
	public static function getCount($table_name, $where = "", $field = "*") {
		if($where) {
			$where = 'WHERE '.$where;
		}
		
		$results = self::execute_sql("SELECT $field FROM ". self::table($table_name) ." $where");
		return $results->rowCount();
	}

	//获取完整表名
	public static function table($table_name) {
		$table_name = explode(',', $table_name);
		foreach($table_name as $key => $name) {
			$table_name[$key] = self::$table_prefix . trim($name);
		}
		return implode(",", $table_name);
	}

	/*	
	 * 执行一条sql语句 
	 * @param $sql sql语句	 
	 */	
	private static function execute_sql($sql) {
		$results = self::$_connectSource->prepare($sql);
		$results->execute();
		self::error($results);
		return $results;
	}

	/*	
	 * 处理多条数据数组	 
	 * @param $sql 字段	 
	 */		
	private static function getValues($sql) {
		foreach($sql as $key => $value) {
			if(is_array($value)) {
				foreach($value as $k => $v) {
					$temp[$k][] = $v;
				}
			}
			else {
				$temp[0][] = $value;
			}
		}

		foreach($temp as $key => $val) {
			$values[$key] = "('" . implode("','", $val) . "')";
		}

		$fields = implode(",", array_keys($sql));
		$values = implode(",", $values);
		
		return "($fields) VALUES $values";
	}
	
	/*
	 * 抛出错误信息
	 */
	private static function error( $pdo ) {
		if( $pdo->errorCode() != 00000 ){ 
			throw new \Exception('SQL错误: ' . json_encode($pdo->errorInfo()));
			exit;
		}
	}
}